package search;

import interfaces.SearchDataBase;
import interfaces.SearchEngine;

import java.util.Date;
import java.util.Vector;

import logger.ForumLogger;
import search.items.UpdatePostQueueItem;
import search.items.deletedPostQueueItem;
import search.items.newPostQueueItem;
import domain.items.Post;

public class WsepSearchEngine implements SearchEngine {

	/** The data base for the search */
	private SearchDataBase _searchDB;

/*	/**
	 * name of the file to which the Search DataBase will be saved
	 */
//	public static final String FILE_NAME = "searchDB.xml";

	public WsepSearchEngine(SearchDataBase searchDB) {
		this._searchDB = searchDB;
	}


	/**
	 * @param authorName : the user name of the owner
	 * @return
	 */
	public Vector<Post> searchByAuthor(String authorName) {
		return new Vector<Post>(_searchDB.getUserPosts(authorName));
	}
	/**
	 *
	 */
	public Vector<Post> searchByContent(String sentence) {
		if (sentence.startsWith("\"") && sentence.endsWith("\""))
			return searchBySequence(sentence.substring(1, sentence.length()-1));

		return searchByRandomOrder(sentence);
	}


	/**
	 *
	 */
	public Vector<Post> searchByDate(Date from, Date to) {
		return new Vector<Post>(_searchDB.getPostsByDate(from, to));
	}

	/**
	 *
	 * @param subString
	 * @return
	 */
	private Vector<Post> searchBySequence(String subString) {
		/**
		 * splitting the words in the sentence & turning them to lower case
		 */
		String[] tWords = subString.toLowerCase().split(" ");
		/**
		 * remove all begging marks from the word
		 */
		for(int i=0; i<tWords.length;i++){
			removePunctuationMarks(tWords[i]) ;
		}
		/**
		 * getting for the first word her post references (vector of posts)
		 */
		Vector<Post> tPosts = new Vector<Post>(_searchDB.getWordReference(tWords[0]));
		Vector<Post> tFinalPosts = new Vector<Post>(_searchDB.getWordReference(tWords[0]));
		/**
		 * for each post in the vector
		 * checking if the sentence exists
		 * if false deleting that post
		 */
		for(int i=0; i<tPosts.size();i++){
			if (!tPosts.elementAt(i).getText().toLowerCase().contains(subString.toLowerCase()) &&
				!tPosts.elementAt(i).getName().toLowerCase().contains(subString.toLowerCase()))
			{
				tFinalPosts.remove(i);
			}
		}
		return tFinalPosts;
	}
	/**
	 *
	 * @param sentence
	 * @return
	 */
	private Vector<Post> searchByRandomOrder(String sentence) {
		/**
		 * splitting the words in the sentence & turning them to lower case
		 */
		String[] tWords = sentence.toLowerCase().split(" ");
		Vector<Vector<Post>> tVPosts = new Vector<Vector<Post>>();
		/**
		 * remove all begging marks from the word
		 */
		for(int i=0; i<tWords.length;i++){
			removePunctuationMarks(tWords[i]) ;
		}
		/**
		 * getting for each word her post references (vector of vectors)
		 */
		for(int i=0; i<tWords.length;i++){
			tVPosts.add(new Vector<Post>(_searchDB.getWordReference(tWords[i]))) ;
		}
		/**
		 * starting with the vector of the first word
		 */
		Vector<Post> tPosts = new Vector<Post>(tVPosts.elementAt(0));
		Vector<Post> tFinalPosts = new Vector<Post>(tVPosts.elementAt(0));
		boolean tWordInPost;
		Post tPost;
		/**
		 * for each post in the first vector:
		 * checking if he exists in the other vectors
		 * if false deleting the post from the answer
		 */
		for(int i=0; i<tPosts.size();i++){
			tWordInPost = true;
			tPost = tPosts.elementAt(i);
			for(int k=1;tWordInPost && k<tVPosts.size();k++){

				if(!tVPosts.elementAt(k).contains(tPost)){
					tWordInPost = false;
					tFinalPosts.remove(i);
				}
			}
		}
		return tFinalPosts;
	}

	/**
	 *
	 * @param word
	 * @return
	 */
	private String removePunctuationMarks (String word){
		while (word.startsWith("(")){
			word = word.substring(1);
		}
		while (word.endsWith(".") | word.endsWith(",") | word.endsWith("?") | word.endsWith("!")
				| word.endsWith(")") | word.endsWith("\"") | word.endsWith(":") | word.endsWith("'")){
			word = word.substring(0, word.length()-1);
		}
		return word;
	}

	public void updateSearchDB(Post newPost, Post oldPost) {

		if (oldPost==null){
			addNewPostToQueue(newPost);
		}
		else if (newPost==null){
			addRemovePostToQueue(oldPost);
		}
		else {
			addUpdatedPostToQueue(newPost, oldPost);
		}

	}
	private void addUpdatedPostToQueue(Post newPost, Post oldPost) {
		String tOldTitle = oldPost.getName();
		String tOldContent = oldPost.getText();
		SearchDataUpdatorImp.mySearchQueue.add(new UpdatePostQueueItem(newPost, tOldTitle, tOldContent));

	}
	private void addRemovePostToQueue(Post oldPost) {
		SearchDataUpdatorImp.mySearchQueue.add(new deletedPostQueueItem(oldPost));

	}
	private void addNewPostToQueue(Post newPost) {
		////////////////// SHAI /////////////////
		ForumLogger.logGeneral("added item to searchEngine Queue, its id is - " + newPost.getId());
		///////////////////////////////////////
		SearchDataUpdatorImp.mySearchQueue.add(new newPostQueueItem(newPost));
	}


}
